/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ventas.excel;

import entities.C;
import entities.LineaPedido;
import entities.Pedido;
import entities.Producto;
import entities.ProductoTalla;
import entities.SerieTallaje;
import entities.TallaSerieTallaje;
import facades.ProductoTallaFacade;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import ventas.datamodel.TablaPedidoDataModel;

/**
 *
 * @author damfercer
 */
@ApplicationScoped
public class ExcelPedido implements Serializable{
    private Pedido pedido;
    private HSSFSheet sheet;
    private int currentRow;
    private int currentColumn;
    private final Integer tallas=9;
    private CellStyle boldStyle;
    @Inject
    private TablaPedidoDataModel tablaPedidoDataModel;
    @Inject 
    private ProductoTallaFacade productoTallaFacade;
    
    public HSSFWorkbook hacerExcel(Pedido p){
        this.pedido=p;
        inicializar();
        imprimirDatosCliente();
        imprimirTablaProductos();
        return sheet.getWorkbook();
    }
    
    private void inicializar(){
        HSSFWorkbook workbook=new HSSFWorkbook();
        this.sheet=workbook.createSheet("Pedido");
        currentRow=0;
        currentColumn=0;
        CellStyle style = workbook.createCellStyle();
        Font font = workbook.createFont();
        font.setBoldweight(Font.BOLDWEIGHT_BOLD);
        style.setFont(font);
        this.boldStyle=style;
        this.tablaPedidoDataModel.setPedido(pedido);
    }
    
    private void imprimirDatosCliente(){
        imprimirLineaCliente("Cliente", pedido.getCliente().getNombre());
        imprimirLineaCliente("Razón Social", pedido.getCliente().getRazonSocial());
        imprimirLineaCliente("CIF", pedido.getCliente().getNif());
        imprimirLineaCliente("Dirección", pedido.getCliente().getDireccion());
        imprimirLineaCliente("Localidad", pedido.getCliente().getLocalidad());
        imprimirLineaCliente("Provincia", pedido.getCliente().getProvincia().getDescripcion());
        imprimirLineaCliente("País", pedido.getCliente().getPais().getDescripcion());
        imprimirLineaCliente("Código Postal", pedido.getCliente().getCodigoPostal());
        imprimirLineaCliente("Fecha de Entrega", pedido.getFechaEntrega());
        imprimirLineaCliente("Contacto", pedido.getContacto());
        nuevaFila();
    }
    
    private void imprimirLineaCliente(String textoCabecera, Object texto){
        Row row=sheet.createRow(currentRow);
        Cell cellTituloCliente=row.createCell(currentColumn);
        cellTituloCliente.setCellValue(textoCabecera);
        cellTituloCliente.setCellStyle(boldStyle);
        currentColumn++;
        row.createCell(currentColumn);
        currentColumn++;
        if(texto!=null){
        row.createCell(currentColumn).setCellValue(texto.toString());
        }
        nuevaFila();
    }
    
    
    private void imprimirTablaProductos(){
        BigDecimal total=BigDecimal.ZERO;
        Integer cantidades=0;
        for(C c:tablaPedidoDataModel.getCDePedido()){
            Integer cantidad=0;
            BigDecimal subTotal=BigDecimal.ZERO;
            imprimirLineaC(c);
            for(SerieTallaje serieTallaje: tablaPedidoDataModel.getSeriesTallajeDePedidoYC(c)){
                imprimirLineaSerieTallaje(serieTallaje);
                for(Producto producto: tablaPedidoDataModel.getTodosProductosDePedidoSerieTallajeYC(c, serieTallaje)){
                    SubTotalProducto subTotalProducto=imprimirLineaProducto(producto);
                    cantidad+=subTotalProducto.getCantidadProducto();
                    subTotal=subTotal.add(subTotalProducto.getSubTotalProducto());
                }
            }
            cantidades+=cantidad;
            total=total.add(subTotal);
            imprimirLineaSubTotalesC(c, cantidad, subTotal);
        }
        imprimirTotal(cantidades, total);
    }
    
    private void imprimirTotal(Integer unidades, BigDecimal total){
        nuevaFila();
        Row row=sheet.createRow(currentRow);
        Cell cellSubTotal=row.createCell(currentColumn);
        cellSubTotal.setCellValue("Total");
        cellSubTotal.setCellStyle(boldStyle);
        nuevaFila();
        Row row1=sheet.createRow(currentRow);
        Cell cellUnidades=row1.createCell(currentColumn);
        cellUnidades.setCellValue("Unidades");
        cellUnidades.setCellStyle(boldStyle);
        currentColumn++;
        row1.createCell(currentColumn);
        currentColumn++;
        row1.createCell(currentColumn).setCellValue(unidades);
        nuevaFila();
        Row row2=sheet.createRow(currentRow);
        Cell cellBaseImponible=row2.createCell(currentColumn);
        cellBaseImponible.setCellValue("Base Imponible");
        cellBaseImponible.setCellStyle(boldStyle);
        currentColumn++;
        row2.createCell(currentColumn);
        currentColumn++;
        row2.createCell(currentColumn).setCellValue(total.setScale(2, RoundingMode.HALF_UP)+" €");
        nuevaFila();
        Row row3=sheet.createRow(currentRow);
        Cell cellIva=row3.createCell(currentColumn);
        cellIva.setCellValue("IVA");
        cellIva.setCellStyle(boldStyle);
        currentColumn++;
        row3.createCell(currentColumn);
        currentColumn++;
        row3.createCell(currentColumn).setCellValue(total.multiply(new BigDecimal(0.18)).setScale(2, RoundingMode.HALF_UP)+" €");
        nuevaFila();
        Row row4=sheet.createRow(currentRow);
        Cell cellTotal=row4.createCell(currentColumn);
        cellTotal.setCellValue("Total");
        cellTotal.setCellStyle(boldStyle);
        currentColumn++;
        row4.createCell(currentColumn);
        currentColumn++;
        row4.createCell(currentColumn).setCellValue(total.add(total.multiply(new BigDecimal(0.18))).setScale(2, RoundingMode.HALF_UP) +" €");
    }
    
    private void imprimirLineaC(C c){
        Row row=sheet.createRow(currentRow);
        Cell cellTituloCliente=row.createCell(currentColumn);
        cellTituloCliente.setCellValue(c.getDescripcion());
        cellTituloCliente.setCellStyle(boldStyle);
        nuevaFila();
    }
    
    private void imprimirLineaSubTotalesC(C c, Integer cantidad, BigDecimal subTotal){
        nuevaFila();
        Row row=sheet.createRow(currentRow);
        for (int i = 0; i < tallas+4; i++) {
            row.createCell(currentColumn);
            currentColumn++;
        }
        Cell cellSubTotal=row.createCell(currentColumn);
        cellSubTotal.setCellValue("Subtotal "+c.getDescripcion());
        cellSubTotal.setCellStyle(boldStyle);
        nuevaFila();
        Row row1=sheet.createRow(currentRow);
        for (int i = 0; i < tallas+4; i++) {
            row1.createCell(currentColumn);
            currentColumn++;
        }
        Cell cellUnidades=row1.createCell(currentColumn);
        cellUnidades.setCellValue("Unidades");
        cellUnidades.setCellStyle(boldStyle);
        currentColumn++;
        Cell cellTituloSubtotal=row1.createCell(currentColumn);
        cellTituloSubtotal.setCellValue("Subtotal");
        cellTituloSubtotal.setCellStyle(boldStyle);
        currentColumn++;
        nuevaFila();
        Row row2=sheet.createRow(currentRow);
        for (int i = 0; i < tallas+4; i++) {
            row2.createCell(currentColumn);
            currentColumn++;
        }
        row2.createCell(currentColumn).setCellValue(cantidad);
        currentColumn++;
        row2.createCell(currentColumn).setCellValue(subTotal.setScale(2,RoundingMode.HALF_UP) +" €");
        nuevaFila();
    }
    
    private void imprimirLineaSerieTallaje(SerieTallaje serieTallaje){
        Row row=sheet.createRow(currentRow);
        for(int i=0; i<4;i++){
            row.createCell(currentColumn);
            currentColumn++;
        }
        Integer tallasAImprimir=tallas;
        for(TallaSerieTallaje tallaSerieTallaje: serieTallaje.getTallaSerieTallajeList()){
            Cell cellTituloCliente=row.createCell(currentColumn);
            cellTituloCliente.setCellValue(tallaSerieTallaje.getTalla().getDescripcion());
            cellTituloCliente.setCellStyle(boldStyle);
            currentColumn++;
            tallasAImprimir--;
        }
        for(int j=0; j<tallasAImprimir;j++){
            row.createCell(currentColumn);
            currentColumn++;
        }
        Cell cellTituloUnidades=row.createCell(currentColumn);
        cellTituloUnidades.setCellValue("Unidades");
        cellTituloUnidades.setCellStyle(boldStyle);
        currentColumn++;
        Cell cellTituloPvp=row.createCell(currentColumn);
        cellTituloPvp.setCellValue("Pvp");
        cellTituloPvp.setCellStyle(boldStyle);
        currentColumn++;
        Cell cellTituloCoste=row.createCell(currentColumn);
        cellTituloCoste.setCellValue("Coste");
        cellTituloCoste.setCellStyle(boldStyle);
        currentColumn++;
        Cell cellTituloSubtotal=row.createCell(currentColumn);
        cellTituloSubtotal.setCellValue("Subtotal");
        cellTituloSubtotal.setCellStyle(boldStyle);
        currentColumn++;
        nuevaFila();
    }
    
    private SubTotalProducto imprimirLineaProducto(Producto producto){
        Integer cantidad=0;
        BigDecimal subTotal=BigDecimal.ZERO;
        Row row=sheet.createRow(currentRow);
        row.createCell(currentColumn).setCellValue(producto.getDescripcion());
        currentColumn++;
        row.createCell(currentColumn);
        currentColumn++;
        row.createCell(currentColumn).setCellValue(producto.getColor());
        currentColumn++;
        row.createCell(currentColumn);
        currentColumn++;
        Integer tallasAImprimir=tallas;
        for(TallaSerieTallaje tallaSerieTallaje: producto.getSerieTallaje().getTallaSerieTallajeList()){
            ProductoTalla productoTalla=productoTallaFacade.getProductoTallaDeProductoYTalla(producto, tallaSerieTallaje.getTalla());
            row.createCell(currentColumn).setCellValue(getCantidadDeProductoTalla(productoTalla));
            cantidad+=getCantidadDeProductoTalla(productoTalla);
            currentColumn++;
            tallasAImprimir--;
        }
        for(int j=0; j<tallasAImprimir;j++){
            row.createCell(currentColumn);
            currentColumn++;
        }
        row.createCell(currentColumn).setCellValue(cantidad);
        currentColumn++;
        row.createCell(currentColumn).setCellValue(producto.getPvp().setScale(2, RoundingMode.HALF_UP)+" €");
        currentColumn++;
        row.createCell(currentColumn).setCellValue(producto.getPvp().divide(pedido.getCliente().getMultiplicador()).setScale(2, RoundingMode.HALF_UP)+" €");
        currentColumn++;
        row.createCell(currentColumn).setCellValue(producto.getPvp().divide(pedido.getCliente().getMultiplicador()).multiply(new BigDecimal(cantidad)).setScale(2, RoundingMode.HALF_UP)+" €");
        currentColumn++;
        nuevaFila();
        return new SubTotalProducto(cantidad, producto.getPvp().divide(pedido.getCliente().getMultiplicador()).multiply(new BigDecimal(cantidad)).setScale(2, RoundingMode.HALF_UP));
    }
    
    private void nuevaFila(){
        this.currentRow++;
        this.currentColumn=0;
    }
    
    private Integer getCantidadDeProductoTalla(ProductoTalla productoTalla){
        Integer cantidad=0;
        for(LineaPedido lineaPedido: pedido.getLineaPedidoList()){
            if(lineaPedido.getProductoTalla().equals(productoTalla)){
                cantidad=lineaPedido.getCantidad();
                break;
            }
        }
        return cantidad;
    }
    
    private class SubTotalProducto{
        private Integer cantidadProducto;
        private BigDecimal subTotalProducto;
        
        public SubTotalProducto(Integer cantidad, BigDecimal subTotal){
            this.cantidadProducto=cantidad;
            this.subTotalProducto=subTotal;
        }

        /**
         * @return the cantidadProducto
         */
        public Integer getCantidadProducto() {
            return cantidadProducto;
        }

        /**
         * @param cantidadProducto the cantidadProducto to set
         */
        public void setCantidadProducto(Integer cantidadProducto) {
            this.cantidadProducto = cantidadProducto;
        }

        /**
         * @return the subTotalProducto
         */
        public BigDecimal getSubTotalProducto() {
            return subTotalProducto;
        }

        /**
         * @param subTotalProducto the subTotalProducto to set
         */
        public void setSubTotalProducto(BigDecimal subTotalProducto) {
            this.subTotalProducto = subTotalProducto;
        }
        
    }  
}
